#ifndef Token_First
#define Token_First
#ifdef __GNUG__
#pragma interface
#endif

#include "Rectangle.h"

enum EvtCursorDir {
	eCrsUp,
	eCrsDown,
	eCrsLeft,
	eCrsRight
};

enum EventCodes {
	eEvtAscFirst    = 0,
	eEvtAscLast     = 127,
	eEvtMetaFirst   = 128,   // returned if key depressed with 'Left' or 'Right' key
	eEvtMetaLast    = 255,
	eEvtPseudo      = 0x7f << 8,
		eEvtLocMove     = eEvtPseudo + 0,
		eEvtEnter       = eEvtPseudo + 2,
		eEvtExit        = eEvtPseudo + 3,
		eEvtLocMoveBut  = eEvtPseudo + 4,
		eEvtButtons     = eEvtPseudo + 32,
			eEvtLeftButton  = eEvtButtons + 0,
			eEvtMiddleButton= eEvtButtons + 1,
			eEvtRightButton = eEvtButtons + 2,
		eEvtPfkFirst    = eEvtPseudo + 42,
			eEvtPfkLast     = eEvtPfkFirst + 64,
		eEvtFirstCursorKey= eEvtPseudo + 128,
			eEvtCursorUp    = eEvtFirstCursorKey + eCrsUp,
			eEvtCursorDown  = eEvtFirstCursorKey + eCrsDown,
			eEvtCursorLeft  = eEvtFirstCursorKey + eCrsLeft,
			eEvtCursorRight = eEvtFirstCursorKey + eCrsRight,
				eEvtLastCursorKey= eEvtCursorRight
};

enum EventFlags {
	eFlgNone        = 0,

	eFlgButDown     = BIT(0),
	eFlgShiftKey    = BIT(1),
	eFlgCntlKey     = BIT(2),
	eFlgMetaKey     = BIT(3) // left or right keys on SUN-2 and SUN-3 keyboards
};

class Token {
public:
	short Code;   // enum EventCodes
	short Flags;  // enum EventFlags
	u_long At;
	Point Pos;

public:
	Token();
	Token(EventCodes, EventFlags f= eFlgNone, Point pos= gPoint0);
	Token(const Token &t);

	bool DoubleClick(const Token &t) const;
	bool IsAscii() const
		{ return (bool) (Code >= eEvtAscFirst && Code <= eEvtAscLast); }
	bool IsKey() const
		{ return (bool) (Code >= eEvtAscFirst && Code <= eEvtMetaLast); }
	bool IsFunctionKey() const
		{ return (bool) (Code >= eEvtPfkFirst && Code <= eEvtPfkLast); }
	bool IsCursorKey() const
		{ return (bool) (Code >= eEvtFirstCursorKey && Code <= eEvtLastCursorKey); }

	bool IsShift() const
		{ return Flags & eFlgShiftKey; }
	bool IsControl() const
		{ return Flags & eFlgCntlKey; }
	bool IsMeta() const
		{ return Flags & eFlgMetaKey; }

	bool IsButtonClick(EventCodes ec) const
		{ return Code == ec && !(Flags & eFlgButDown); }
	bool IsLeftClick() const
		{ return IsButtonClick(eEvtLeftButton); }
	bool IsMiddleClick() const
		{ return IsButtonClick(eEvtMiddleButton); }
	bool IsRightClick() const
		{ return IsButtonClick(eEvtRightButton); }
	bool IsMouseButton() const
		{ return (bool) (Code >= eEvtButtons && Code <= eEvtRightButton); }
	char MapToAscii() const;
	Point CursorPoint() const;
	EvtCursorDir CursorDir() const
		{ return (EvtCursorDir)((EvtCursorDir)Code - eEvtFirstCursorKey); }
	int FunctionCode() const
		{ return Code - eEvtPfkFirst; }
	void Dump() const;
};

#endif
